package main

/*
设计一个支持 push ，pop ，top 操作，并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

作者：力扣 (LeetCode)
链接：https://leetcode-cn.com/leetbook/read/queue-stack/g5l7d/
来源：力扣（LeetCode）
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
*/

import "fmt"

type MinStack struct {
	arr []int
	top int
	min int
}

func Constructor() MinStack {
	return MinStack{
		arr: make([]int, 0),
		top: -1,
		min: 0,
	}
}

func (this *MinStack) Push(val int) {
	this.top++
	if this.top == 0 {
		this.arr = append(this.arr, 0)
		this.min = val
		return
	}
	if len(this.arr) > this.top {
		this.arr[this.top] = val - this.min
	} else {
		this.arr = append(this.arr, val-this.min)
	}
	if val < this.min {
		this.min = val
	}
}
func (this *MinStack) Show() {
	for i := 0; i <= this.top; i++ {
		fmt.Printf("<-[%d]", this.arr[this.top-i])
	}
	fmt.Println()
	tmp := this.min
	for i := 0; i <= this.top; i++ {
		if this.arr[this.top-i] < 0 {
			fmt.Printf("<-[%d]", tmp)
			tmp = this.min - this.arr[this.top-i]
			continue
		}
		fmt.Printf("<-[%d]", tmp+this.arr[this.top-i])
	}
	fmt.Println()
}

func (this *MinStack) Pop() {
	if this.arr[this.top] < 0 {
		this.min = this.min - this.arr[this.top]
	}
	this.top--
}

func (this *MinStack) GetMin() int {
	return this.min
}

func (this *MinStack) Top() int {
	if this.arr[this.top] <= 0 {
		return this.min
	}
	return this.min + this.arr[this.top]
}

func main() {
	s := Constructor()
	s.Push(-2)
	s.Push(0)
	s.Push(-3)
	s.Show()
	fmt.Println("min:", s.GetMin())
	s.Pop()
	s.Show()
	fmt.Println(s.Top())

}
